فراتر از اصول اولیه فلکسباکس بروید. بر ترازبندی و توزیع پیشرفته با align-content، flex-grow، flex-shrink و سناریوهای عملی و واقعی مسلط شوید.
تسلط بر فلکسباکس CSS: ترازبندی و توزیع پیشرفته
برای چندین سال، فلکسباکس CSS سنگ بنای چیدمان وب مدرن بوده است. اکثر توسعهدهندگان با استفاده از display: flex برای تراز کردن آیتمها در یک ردیف یا ایجاد کامپوننتهای ساده در مرکز، احساس راحتی میکنند. با این حال، تسلط واقعی بر فلکسباکس در درک ویژگیهای ظریفتر آن برای ترازبندی پیشرفته و توزیع پویا نهفته است. هنگامی که از اصول اولیه justify-content: center و align-items: center فراتر میروید، قدرت ایجاد چیدمانهای پیچیده، واکنشگرا و ذاتاً انعطافپذیر را با سهولت شگفتانگیزی به دست میآورید.
این راهنما برای توسعهدهندگانی است که اصول اولیه را میدانند اما میخواهند درک خود را عمیقتر کنند. ما ویژگیهایی را که ترازبندی چندخطی را کنترل میکنند، منطق پیچیده پشت نحوه رشد و کوچک شدن آیتمهای flex و چندین الگوی قدرتمند که چالشهای رایج چیدمان را حل میکنند، بررسی خواهیم کرد. آماده شوید تا از یک کاربر معمولی به یک معمار با اعتماد به نفس فلکسباکس تبدیل شوید.
پایه و اساس: یادآوری سریع محورهای اصلی و متقاطع
قبل از پرداختن به مباحث پیشرفته، داشتن درک کاملاً محکم از دو محوری که بر هر کانتینر flex حاکم هستند، حیاتی است. تمام ویژگیهای ترازبندی و توزیع در فلکسباکس در امتداد یکی از این دو محور عمل میکنند.
- محور اصلی (Main Axis): این محور اصلی است که آیتمهای flex در امتداد آن چیده میشوند. جهت آن توسط ویژگی
flex-directionتعریف میشود. - محور متقاطع (Cross Axis): این محور همیشه عمود بر محور اصلی است.
نکته کلیدی این است که این محورها ثابت نیستند. آنها بر اساس مقدار flex-direction شما جهتگیری مجدد میکنند:
flex-direction: row(پیشفرض): محور اصلی افقی (چپ به راست) و محور متقاطع عمودی (بالا به پایین) است.flex-direction: column: محور اصلی عمودی (بالا به پایین) و محور متقاطع افقی (چپ به راست) میشود.flex-direction: row-reverse: محور اصلی افقی است اما از راست به چپ اجرا میشود.flex-direction: column-reverse: محور اصلی عمودی است اما از پایین به بالا اجرا میشود.
فراموش کردن این مفهوم اساسی منشأ بیشتر سردرگمیها در فلکسباکس است. همیشه از خود بپرسید: «محور اصلی من به کدام سمت اشاره میکند؟» قبل از اعمال یک ویژگی ترازبندی.
تسلط بر توزیع در محور اصلی با justify-content
ویژگی justify-content نحوه توزیع فضا بین و اطراف آیتمهای flex در امتداد محور اصلی را کنترل میکند. در حالی که flex-start، flex-end و center ساده هستند، قدرت واقعی در مقادیر توزیع فضا نهفته است.
نگاهی عمیقتر به توزیع فضا
بیایید تفاوتهای ظریف اما حیاتی بین space-between، space-around و space-evenly را روشن کنیم.
-
justify-content: space-between;این مقدار آیتمها را به طور مساوی در محور اصلی توزیع میکند. اولین آیتم به ابتدای کانتینر و آخرین آیتم به انتهای آن رانده میشود. تمام فضای باقیمانده به طور مساوی بین آیتمها تقسیم میشود. در لبههای بیرونی فضایی وجود ندارد.
مورد استفاده: برای نوارهای ناوبری که میخواهید لوگو در سمت چپ و لینکها در سمت راست باشند، با فاصلهگذاری مساوی بین لینکها، عالی است.
-
justify-content: space-around;این مقدار آیتمها را با فضای مساوی اطراف هر آیتم توزیع میکند. تصور کنید هر آیتم یک «حباب» فضا در دو طرف چپ و راست خود دارد. وقتی حبابهای آیتمهای مجاور به هم میرسند، فضای بین آنها دو برابر فضای لبههای کانتینر به نظر میرسد. به طور خاص، فضای لبههای بیرونی نصف اندازه فضای بین آیتمها است.
مورد استفاده: برای چیدمان کارتها یا گالریها که میخواهید آیتمها از لبههای کانتینر فاصله داشته باشند اما کاملاً به آنها نچسبیده باشند، مفید است.
-
justify-content: space-evenly;این شهودیترین مقدار از این سه است. این تضمین میکند که فضای بین هر دو آیتم دقیقاً با فضای بین اولین/آخرین آیتم و لبه کانتینر یکسان است. هر شکافی یکسان است.
مورد استفاده: ایدهآل برای زمانی که به یک چیدمان کاملاً متعادل و متقارن نیاز دارید. این اغلب همان چیزی است که طراحان به طور ضمنی هنگام درخواست «فاصلهگذاری مساوی» میخواهند.
غلبه بر ترازبندی محور متقاطع با align-items و align-self
در حالی که justify-content محور اصلی را مدیریت میکند، align-items ترازبندی پیشفرض آیتمها را در امتداد محور متقاطع در یک خط واحد مدیریت میکند.
درک مقادیر `align-items`
align-items: stretch;(پیشفرض): به همین دلیل است که آیتمهای flex شما اغلب به نظر میرسد ارتفاع کانتینر خود را پر میکنند بدون اینکه شما از آنها بخواهید. آیتمها کشیده میشوند تا اندازه کانتینر را در امتداد محور متقاطع پر کنند (مثلاً ارتفاع در یک کانتینر باflex-direction: row).align-items: flex-start;: آیتمها در ابتدای محور متقاطع جمع میشوند.align-items: flex-end;: آیتمها در انتهای محور متقاطع جمع میشوند.align-items: center;: آیتمها در امتداد محور متقاطع مرکز میشوند.align-items: baseline;: این یک مقدار قدرتمند و کم استفاده است. آیتمها به گونهای تراز میشوند که خطوط پایه متن آنها در یک راستا قرار گیرند. این فوقالعاده مفید است زمانی که آیتمهایی با اندازههای فونت مختلف دارید (مثلاً یک عنوان اصلی در کنار یک زیرنویس) و میخواهید آنها به صورت متنی تراز شوند، نه فقط بر اساس مرزهای جعبهشان.
نادیده گرفتن با align-self
چه میشود اگر بخواهید یک آیتم خاص متفاوت از بقیه رفتار کند؟ اینجاست که align-self وارد میشود. این ویژگی که به یک آیتم flex جداگانه اعمال میشود، ویژگی align-items کانتینر را فقط برای آن آیتم نادیده میگیرد. این ویژگی تمام مقادیر مشابه align-items را میپذیرد (به علاوه `auto` که آن را به مقدار کانتینر بازنشانی میکند).
مثال: یک ردیف از کارتها را تصور کنید که همگی با align-items: center در مرکز قرار گرفتهاند. شما میتوانید با اعمال align-self: stretch; به یک کارت «ویژه»، آن را از بقیه بلندتر کرده و برجسته کنید.
قهرمان گمنام: توزیع پیشرفته با align-content
این مسلماً непоняترین ویژگی در فلکسباکس است و تسلط بر آن نشانه مهارت پیشرفته است. یک نقطه سردرگمی رایج شباهت آن به align-items است.
این قانون حیاتی است: align-content زمانی که همه آیتمهای flex شما در یک خط واحد باشند، هیچ تأثیری ندارد. این فقط زمانی کار میکند که شما یک کانتینر flex چند خطی داشته باشید (یعنی flex-wrap: wrap; را تنظیم کرده باشید و آیتمها واقعاً به خطوط جدید پیچیده شده باشند).
به این صورت فکر کنید:
align-itemsآیتمها را درون خط خودشان تراز میکند.align-contentخود خطوط را درون کانتینر تراز میکند. این ویژگی توزیع فضا در محور متقاطع بین ردیفهای آیتمها را کنترل میکند.
این اساساً مانند justify-content عمل میکند، اما برای محور متقاطع. مقادیر آن تقریباً یکسان هستند:
align-content: flex-start;(پیشفرض): تمام خطوط در ابتدای کانتینر جمع میشوند.align-content: flex-end;: تمام خطوط در انتهای کانتینر جمع میشوند.align-content: center;: تمام خطوط در مرکز کانتینر جمع میشوند.align-content: space-between;: خط اول در ابتدا، خط آخر در انتها و فضا به طور مساوی بین خطوط توزیع میشود.align-content: space-around;: فضای مساوی در اطراف هر خط قرار میگیرد.align-content: space-evenly;: فاصله بین هر خط یکسان است.align-content: stretch;: خطوط کشیده میشوند تا فضای باقیمانده را اشغال کنند.
مورد استفاده: یک گالری عکس را تصور کنید که در آن آیتمها میپیچند. اگر کانتینر ارتفاع ثابتی داشته باشد، ممکن است فضای عمودی اضافی باقی بماند. به طور پیشفرض، این فضا در پایین ظاهر میشود. با استفاده از align-content: space-between; یا align-content: center;، میتوانید توزیع عمودی کل شبکه عکسهای خود را کنترل کنید و یک چیدمان بسیار حرفهایتر ایجاد کنید.
اندازهگیری و توزیع پویا: خلاصه نویسی flex
چیدمانهای استاتیک نادر هستند. قدرت واقعی فلکسباکس از توانایی آن در مدیریت محتوای پویا و فضای موجود ناشی میشود. این کار توسط سه ویژگی کنترل میشود که اغلب از طریق خلاصه نویسی flex تنظیم میشوند: flex-grow، flex-shrink و flex-basis.
۱. flex-basis: نقطه شروع
قبل از اینکه هرگونه رشد یا کوچک شدنی رخ دهد، فلکسباکس به یک اندازه اولیه برای هر آیتم نیاز دارد. این وظیفه flex-basis است. این ویژگی اندازه پیشفرض یک عنصر را در امتداد محور اصلی تعریف میکند.
- اگر روی یک طول مشخص تنظیم شود (مثلاً
200pxیا10rem)، آن اندازه اولیه آیتم میشود. - اگر روی
autoتنظیم شود، به دنبال ویژگی `width` یا `height` روی آیتم میگردد. اگر هیچکدام وجود نداشته باشد، بر اساس محتوای آیتم اندازهگیری میکند. - اگر روی
0تنظیم شود، آیتم اندازه اولیه ندارد و اندازه نهایی آن صرفاً توسط نسبتflex-growآن تعیین میشود.
بهترین روش: اغلب بهتر است به جای `width` در یک زمینه flex از flex-basis استفاده کنید، زیرا در تعریف اندازه آیتم در زمینه محور اصلی صریحتر است.
۲. flex-grow: مصرف فضای مثبت
وقتی کانتینر flex فضای اضافی در امتداد محور اصلی خود دارد، flex-grow تعیین میکند که آن فضا چگونه توزیع شود. این یک نسبت بدون واحد است.
- مقدار پیشفرض
0است، به این معنی که آیتمها برای پر کردن فضای اضافی رشد نخواهند کرد. - اگر همه آیتمها
flex-grow: 1داشته باشند، فضای اضافی به طور مساوی بین آنها توزیع میشود. - اگر یک آیتم
flex-grow: 2و دیگریflex-grow: 1داشته باشد، آیتم اول دو برابر آیتم دوم از فضای اضافی دریافت خواهد کرد.
۳. flex-shrink: مدیریت فضای منفی (سرریز)
این همتای `flex-grow` است. وقتی فضای کافی در کانتینر برای جا دادن همه آیتمها در flex-basis خود وجود ندارد، آنها باید کوچک شوند. flex-shrink کنترل میکند که چقدر کوچک شوند.
- مقدار پیشفرض
1است، به این معنی که همه آیتمها به طور پیشفرض به نسبت کوچک میشوند تا از سرریز جلوگیری کنند. - اگر
flex-shrink: 0را روی یک آیتم تنظیم کنید، آن آیتم کوچک نخواهد شد. اندازهflex-basisخود را حفظ میکند و به طور بالقوه باعث سرریز شدن کانتینر میشود. این برای عناصری مانند لوگوها یا دکمهها که هرگز نباید فشرده شوند، مفید است.
خلاصه نویسی flex: کنار هم قرار دادن همه چیز
ویژگی flex یک خلاصه نویسی برای flex-grow، flex-shrink و flex-basis به همین ترتیب است.
flex: 0 1 auto;(پیشفرض): آیتم نمیتواند رشد کند، میتواند کوچک شود و مبنای آن توسط عرض/ارتفاع یا محتوای آن تعیین میشود.flex: 1;(خلاصه نویسی برایflex: 1 1 0;): یک مقدار بسیار رایج. آیتم میتواند رشد و کوچک شود و اندازه اولیه آن 0 است. این به طور موثر باعث میشود آیتمها فضا را صرفاً بر اساس نسبت flex-grow خود به اشتراک بگذارند.flex: auto;(خلاصه نویسی برایflex: 1 1 auto;): آیتم میتواند رشد و کوچک شود و مبنای آن توسط محتوای آن تعیین میشود. این به آیتمها اجازه میدهد تا بر اساس محتوای خود اندازههای متفاوتی داشته باشند، اما همچنان به طور انعطافپذیر فضای اضافی را جذب کنند.flex: none;(خلاصه نویسی برایflex: 0 0 auto;): آیتم کاملاً غیرقابل انعطاف است. نمیتواند رشد یا کوچک شود.
موارد استفاده عملی و سناریوهای پیشرفته
سناریو ۱: فوتر چسبان (چیدمان جام مقدس)
یک مشکل کلاسیک طراحی وب: چگونه یک فوتر را به پایین صفحه بچسبانیم، حتی زمانی که محتوا کوتاه است، اما زمانی که محتوا طولانی است به طور طبیعی به پایین رانده شود.
.page-container {
display: flex;
flex-direction: column;
min-height: 100vh; /* Viewport Height */
}
.main-content {
flex-grow: 1; /* or flex: 1; */
}
با تبدیل کانتینر اصلی صفحه به یک فلکسباکس ستونی و تنظیم ناحیه محتوای اصلی روی flex-grow: 1، به آن میگوییم که تمام فضای عمودی موجود را مصرف کند و فوتر را به پایین ویوپورت هل دهد.
سناریو ۲: حاشیههای خودکار برای جداسازی گروهها
چگونه یک نوار ناوبری با یک لوگو در سمت چپ و گروهی از لینکها در سمت راست ایجاد میکنید؟ در حالی که justify-content: space-between کار میکند اگر لوگو یک آیتم flex واحد باشد، چه میشود اگر چندین آیتم در سمت راست داشته باشید؟
راه حل، جادوی حاشیههای خودکار در فلکسباکس است.
.navbar {
display: flex;
}
.logo {
/* No special properties needed */
}
.nav-links {
margin-left: auto;
}
در یک کانتینر flex، یک حاشیه خودکار با حرص تمام فضای موجود را در جهتی که اعمال شده است مصرف میکند. با تنظیم margin-left: auto روی گروه لینکهای ناوبری، یک فضای خالی و انعطافپذیر بین لوگو و لینکها ایجاد میکند و لینکها را تا انتها به سمت راست هل میدهد.
سناریو ۳: شیء رسانهای (Media Object)
یک الگوی رایج UI شامل یک تصویر یا آیکون در یک طرف و متن توصیفی در طرف دیگر است. متن باید تمام فضای باقیمانده را اشغال کند و به زیبایی بپیچد.
.media-object {
display: flex;
align-items: flex-start; /* Aligns image and text to the top */
}
.media-image {
margin-right: 1rem;
flex-shrink: 0; /* Prevents the image from being squished */
}
.media-body {
flex-grow: 1; /* Takes up all remaining horizontal space */
}
در اینجا، flex-grow: 1 روی کانتینر متن کلید اصلی است. این تضمین میکند که مهم نیست تصویر چقدر عرض داشته باشد، بدنه متن برای پر کردن بقیه عرض موجود در کانتینر گسترش مییابد.
نتیجهگیری: فراتر از ترازبندی، به سوی چیدمان هدفمند
تسلط بر فلکسباکس به معنای فراتر رفتن از صرفاً مرکز قرار دادن چیزها است. این در مورد درک تعامل بین محورها، منطق توزیع فضا و انعطافپذیری اندازهگیری آیتمها است. با به دست آوردن درک قوی از align-content برای چیدمانهای چند خطی، خلاصه نویسی flex برای اندازهگیری پویا و الگوهای قدرتمندی مانند حاشیههای خودکار، میتوانید چیدمانهایی بسازید که نه تنها از نظر بصری جذاب هستند، بلکه قوی، واکنشگرا و از نظر معنایی تمیز نیز هستند.
دفعه بعد که با یک چالش چیدمان پیچیده روبرو شدید، در برابر وسوسه استفاده از floatها یا هکهای موقعیتیابی پیچیده مقاومت کنید. در عوض، از خود بپرسید: آیا این مشکل با توزیع هدفمند فضا قابل حل است؟ پاسخ، اغلب اوقات، در قابلیتهای پیشرفته فلکسباکس CSS یافت خواهد شد.